home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH7 / SRC / OBJ4PICT.CLS < prev    next >
Encoding:
Text File  |  1995-10-26  |  5.6 KB  |  203 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "ObjPicture"
  6. Attribute VB_Creatable = False
  7. Attribute VB_Exposed = False
  8. Option Explicit
  9.  
  10. ' Each ObjPicture object is a quadtree node.
  11. '
  12. ' If the object is a leaf node, its Objects
  13. ' collection contains the objects to draw.
  14. '
  15. ' Otherwise the object's children contain other
  16. ' ObjPicture objects.
  17.  
  18. ' The maximum number of objects the node can hold.
  19. Const MAX_OBJECTS = 100
  20.  
  21. ' The bounds this quadtree node represents.
  22. Public xmin As Single
  23. Public ymin As Single
  24. Public xmid As Single
  25. Public ymid As Single
  26. Public xmax As Single
  27. Public ymax As Single
  28.  
  29. ' The objects, if this is a leaf node.
  30. Private Objects As Collection
  31.  
  32. ' The quadtree children otherwise.
  33. Public NWchild As ObjPicture
  34. Public NEchild As ObjPicture
  35. Public SWchild As ObjPicture
  36. Public SEchild As ObjPicture
  37.  
  38. ' ************************************************
  39. ' Find an object that contains this point.
  40. ' ************************************************
  41. Function NearestObject(x As Single, y As Single) As Object
  42. Dim obj As Object
  43.  
  44.     Set NearestObject = Nothing
  45.     ' Bail out if we don't contain the point.
  46.     If x < xmin Or x > xmax Or _
  47.        y < ymin Or y > ymax _
  48.        Then Exit Function
  49.        
  50.     ' Find the object.
  51.     If Objects Is Nothing Then
  52.         If y > ymid Then
  53.             If x < xmid Then
  54.                 Set NearestObject = NWchild.NearestObject(x, y)
  55.             Else
  56.                 Set NearestObject = NEchild.NearestObject(x, y)
  57.             End If
  58.         Else
  59.             If x < xmid Then
  60.                 Set NearestObject = SWchild.NearestObject(x, y)
  61.             Else
  62.                 Set NearestObject = SEchild.NearestObject(x, y)
  63.             End If
  64.         End If
  65.     Else
  66.         For Each obj In Objects
  67.             If obj.Contains(x, y) Then
  68.                 Set NearestObject = obj
  69.                 Exit Function
  70.             End If
  71.         Next obj
  72.     End If
  73. End Function
  74.  
  75. ' ************************************************
  76. ' Set the Drawn properties of the objects.
  77. ' ************************************************
  78. Sub SetDrawn(value As Boolean)
  79. Dim obj As Object
  80.  
  81.     If Objects Is Nothing Then
  82.         NWchild.SetDrawn value
  83.         NEchild.SetDrawn value
  84.         SWchild.SetDrawn value
  85.         SEchild.SetDrawn value
  86.     Else
  87.         For Each obj In Objects
  88.             obj.Drawn = value
  89.         Next obj
  90.     End If
  91. End Sub
  92.  
  93. ' ************************************************
  94. ' Add an object to the Objects collection.
  95. '
  96. ' If this gives us too many, create child nodes
  97. ' and subdivide.
  98. ' ************************************************
  99. Sub Add(obj As Object)
  100.     If Objects Is Nothing Then
  101.         PlaceObject obj
  102.     Else
  103.         Objects.Add obj
  104.         If Objects.Count > MAX_OBJECTS Then Divide
  105.     End If
  106. End Sub
  107.  
  108. ' ************************************************
  109. ' Create the children and divide the object.
  110. ' ************************************************
  111. Sub Divide()
  112. Dim obj As Object
  113.     
  114.     ' Create the children.
  115.     Set NWchild = New ObjPicture
  116.     NWchild.SetBounds xmin, xmid, ymid, ymax
  117.         
  118.     Set NEchild = New ObjPicture
  119.     NEchild.SetBounds xmid, xmax, ymid, ymax
  120.     
  121.     Set SWchild = New ObjPicture
  122.     SWchild.SetBounds xmin, xmid, ymin, ymid
  123.     
  124.     Set SEchild = New ObjPicture
  125.     SEchild.SetBounds xmid, xmax, ymin, ymid
  126.         
  127.     ' Divide up the children.
  128.     For Each obj In Objects
  129.         PlaceObject obj
  130.     Next obj
  131.  
  132.     ' Remove the Objects collection.
  133.     Set Objects = Nothing
  134. End Sub
  135.  
  136. ' ************************************************
  137. ' Set the bounds for this quadtree node.
  138. ' ************************************************
  139. Sub SetBounds(x1 As Single, x2 As Single, y1 As Single, y2 As Single)
  140.     xmin = x1
  141.     ymin = y1
  142.     xmax = x2
  143.     ymax = y2
  144.     xmid = (xmin + xmax) / 2
  145.     ymid = (ymin + ymax) / 2
  146. End Sub
  147. ' ************************************************
  148. ' Place this object in the proper child(ren).
  149. ' ************************************************
  150. Sub PlaceObject(obj As Object)
  151. Dim x1 As Single
  152. Dim x2 As Single
  153. Dim y1 As Single
  154. Dim y2 As Single
  155.         
  156.     obj.Bound x1, y1, x2, y2
  157.     If y2 > ymid And x1 < xmid Then NWchild.Add obj
  158.     If y2 > ymid And x2 > xmid Then NEchild.Add obj
  159.     If y1 < ymid And x1 < xmid Then SWchild.Add obj
  160.     If y1 < ymid And x2 > xmid Then SEchild.Add obj
  161. End Sub
  162.  
  163. ' ************************************************
  164. ' Draw the picture on a Form, Printer, or
  165. ' PictureBox.
  166. ' ************************************************
  167. Sub Draw(canvas As Object, x1 As Single, y1 As Single, x2 As Single, y2 As Single)
  168. Dim obj As Object
  169. Dim oldcolor As Long
  170.  
  171.     ' Bail out if we don't intersect the region
  172.     ' we're trying to draw.
  173.     If x2 < xmin Or x1 > xmax Or _
  174.        y2 < ymin Or y1 > ymax _
  175.        Then Exit Sub
  176.        
  177.     ' Draw a red box around our display region.
  178.     oldcolor = canvas.ForeColor
  179.     canvas.ForeColor = RGB(255, 0, 0)
  180.     canvas.Line (xmin, ymin)-(xmax, ymax), , B  '@
  181.     canvas.ForeColor = oldcolor
  182.     
  183.     If Objects Is Nothing Then
  184.         NWchild.Draw canvas, x1, y1, x2, y2
  185.         NEchild.Draw canvas, x1, y1, x2, y2
  186.         SWchild.Draw canvas, x1, y1, x2, y2
  187.         SEchild.Draw canvas, x1, y1, x2, y2
  188.     Else
  189.         For Each obj In Objects
  190.             obj.Draw canvas
  191.         Next obj
  192.     End If
  193. End Sub
  194.  
  195. ' ************************************************
  196. ' Start with an empty Objects collection.
  197. ' ************************************************
  198. Private Sub Class_Initialize()
  199.     Set Objects = New Collection
  200. End Sub
  201.  
  202.  
  203.